/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-13
 * V4.0
 */
package com.jphenix.webserver.instancea;

import com.jphenix.share.lang.SString;
import com.jphenix.share.util.BaseUtil;
import com.jphenix.standard.docs.ClassInfo;

import java.io.File;
import java.io.FilenameFilter;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;

/**
 * 路径工具
 * @author 刘虻
 * 2009-12-10下午06:15:27
 */
@ClassInfo({"2014-06-13 17:17","路径工具"})
public class PathUtil {

	/**
	 * 获取指定最近的文件
	 * @author 刘虻
	 * 2009-12-10下午06:18:08
	 * @param fileName 文件名
	 * @param basePath 搜索根路径
	 * @param jumpPath 跳过指定路径
	 * @return 文件全路径
	 */
	public static String getNearPath(String fileName,String basePath,String jumpPath) {
		if(basePath==null || basePath.length()<1) {
			basePath = getThisPath(null);
		}
		String rePath = null; //返回值
		while(true) {
			rePath = getFileByPath(basePath,jumpPath,fileName);
			jumpPath = basePath;
			if(rePath==null) {
				basePath = fixUpPath(basePath+"/../");
				if(jumpPath.equals(basePath)) {
					//已经到了根路径，也没找到文件
					return null;
				}
			}else {
				return fixPath(rePath);
			}
		}
	}
	
	/**
	 * 获取指定类的根路径
	 * @author 刘虻
	 * 2009-12-10下午06:17:03
	 * @param classPath 类路径
	 * @return 指定类的根路径
	 */
	public static String getThisPath(String classPath) {
		Class<?> inCls = null; //定位类
		if(classPath!=null) {
			try {
				inCls = Class.forName(classPath);
			}catch(Exception e) {}
		}
		if(inCls==null) {
			inCls = PathUtil.class;
		}
		//获取当前类URL
		URL url = 
			(inCls.getProtectionDomain()).getCodeSource().getLocation();
		//获取返回值
		String rePath = url.getPath();
		//获取路径
		try {
			//从Class中获取到的路径都是UTF-8编码格式的
			rePath = URLDecoder.decode(rePath,"UTF-8");
		}catch(Exception e) {}
		//去掉文件名
		rePath = rePath.substring(0,rePath.lastIndexOf("/")+1);
    	return rePath;
    }
	
	
	/**
	 * 整理文件路径
	 * @author 刘虻
	 * 2009-12-11上午10:14:08
	 * @param dummyPath 待整理的路径
	 * @return
	 */
	protected static String fixPath(String dummyPath) {
    	//处理路径中可能出现错误的分隔符
		dummyPath = BaseUtil.swapString(dummyPath,"\\","/");
    	dummyPath = BaseUtil.swapString(dummyPath,"///","/");
    	dummyPath = BaseUtil.swapString(dummyPath,"//","/");
    	return dummyPath;
	}
	
	   
    /**
     * 处理路径中的通配符
     * @author 刘虻
     * 2009-11-10下午03:09:56
     * @param dummyPath 待处理路径
     * @return 处理后的路径
     */
    public static String fixUpPath(String dummyPath) {
    	dummyPath = fixPath(dummyPath);
    	StringBuffer rePathSbf = new StringBuffer(); //构造返回路径
    	if (dummyPath.startsWith("/")) {
    		rePathSbf.append("/");
    		dummyPath = dummyPath.substring(1);
    	}else if (dummyPath.indexOf(":/")==1) {
    		rePathSbf.append(dummyPath, 0, 3);
    		dummyPath = dummyPath.substring(3);
    	}else if (dummyPath.indexOf(":/")==2) {
    		rePathSbf.append(dummyPath, 0, 4);
    		dummyPath = dummyPath.substring(4);
    	}
    	//分割成文件夹名
    	List<String> pathSubArrayList = BaseUtil.splitToList(dummyPath,"/");
    	//整理后的文件夹序列
    	ArrayList<String> fixArrayList = new ArrayList<String>();
    	boolean isWar = false; //是否为war
    	if (pathSubArrayList!=null) {
    		for (String thisPath:pathSubArrayList) {
    			//endsWith("!") 是因为如果部署成war格式 war文件名与展开时的根路径名不同
    			if ("..".equals(thisPath)) {
    				if (fixArrayList.size()>0 ) {
    					if (SString.valueOf(fixArrayList.get(fixArrayList.size()-1)).endsWith("!")) {
    						isWar = true;
    					}else {
    						fixArrayList.remove(fixArrayList.size()-1);
    					}
    				}
    			}else {
    				if (isWar) {
    					isWar = false;
    				}else {
    					fixArrayList.add(thisPath);
    				}
    			}
    		}
    	}
    	for (int i=0;i<fixArrayList.size();i++) {
    		if (i>0) {
    			rePathSbf.append("/");
    		}
    		rePathSbf.append(fixArrayList.get(i));
    	}
    	return rePathSbf.toString();
    }
    
	
	/**
	 * 搜索指定文件夹中的指定文件
	 * @author 刘虻
	 * 2009-12-11上午10:00:04
	 * @param basePath 搜索根路径
	 * @param jumpPath 跳过不搜索的全路径
	 * @param fileName 搜索文件名
	 * @return 搜索到的文件全路径，没搜索到为空
	 */
	protected static String getFileByPath(String basePath,String jumpPath,String fileName) {
    	//构建根路径对象
    	File file = new File(basePath);
    	final String fName = fileName; //终态文件名
    	final ArrayList<String> pathList = new ArrayList<String>(); //子文件夹序列
    	final ArrayList<String> fileList = new ArrayList<String>(); //符合条件的文件序列 通常只有一个
    	file.list(new FilenameFilter() {
            //文件筛选类
            @Override
            public boolean accept(File dirPathFile, String lastNameStr) {
            	//全路径
            	String allPath = fixPath(dirPathFile.getPath()+"/"+lastNameStr);
                try{
                	if(lastNameStr.equalsIgnoreCase(fName)) {
                		fileList.add(allPath);
                		return true;
                	}
                	//检测是否为文件夹
                	File file = new File(allPath);
                	if(file.isDirectory()) {
                		if(!allPath.startsWith("/")) {
                			allPath = "/"+allPath;
                		}
                		allPath += "/";
                		pathList.add(allPath);
                		return false;
                	}
                }catch(Exception e) {}
                return false;
            }
        });
       	if(fileList.size()>0) {
       		//获取到了返回值
       		return SString.valueOf(fileList.get(0));
       	}
       	for(String sPath:pathList) {
       		if(jumpPath==null || !sPath.equalsIgnoreCase(jumpPath)) {
       			//获取返回值
       			String rePath = getFileByPath(sPath,null,fileName);
       			if(rePath!=null) {
       				return rePath;
       			}
       		}
       	}
       	return null;
    }
	
	/**
	 * 获取指定文件路径所在的文件夹路径
	 * @author 刘虻
	 * 2009-12-11下午02:10:59
	 * @param filePath 文件路径
	 * @return 文件夹路径
	 */
	public static String getFilePath(String filePath) {
		if(filePath==null) {
			return "";
		}
		filePath = fixUpPath(filePath);
		//路径分割点
		int point = filePath.lastIndexOf("/");
		if(point>-1) {
			return filePath.substring(0,point+1);
		}
		return "";
	}
	
	
	/**
	 * 从文件路径中提取文件名
	 * @author 刘虻
	 * 2009-12-10下午06:38:04
	 * @param filePath 文件路径
	 * @return 文件名
	 */
	public static String getFileName(String filePath) {
		if(filePath==null || filePath.length()<1) {
			return "";
		}
		int filePoint = filePath.lastIndexOf("/");
		if(filePoint>0) {
			return filePath.substring(filePoint+1);
		}
		return "";
	}
}
